package com.recharge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.recharge.common.domain.PageDO;
import com.recharge.common.enums.ErrorCode;
import com.recharge.common.result.ResultDO;
import com.recharge.common.result.ResultSupport;
import com.recharge.common.util.BeanUtilsExtends;
import com.recharge.common.util.Constant;
import com.recharge.common.util.PasswordUtil;
import com.recharge.common.util.http.MapTool;
import com.recharge.core.entity.UserDetailEntity;
import com.recharge.core.entity.UserLoginEntity;
import com.recharge.core.entity.UserRoleEntity;
import com.recharge.core.mapper.UserDetailMapper;
import com.recharge.core.mapper.UserLoginMapper;
import com.recharge.core.mapper.UserRoleMapper;
import com.recharge.domain.context.ShiroUtils;
import com.recharge.domain.query.UserQueryDO;
import com.recharge.domain.vo.*;
import com.recharge.service.MerchantService;
import com.recharge.service.RoleService;
import com.recharge.service.UserLoginLogService;
import com.recharge.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.stream.Collectors;

/**
 * <p>
 * 管理员登陆表 服务实现类
 * </p>
 *
 * @author reagan
 * @since 2020-08-14
 */
@Service
public class UserServiceImpl implements UserService {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private UserLoginMapper userLoginMapper;

    @Autowired
    private UserDetailMapper userDetailMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private UserLoginLogService userLoginLogService;

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    public ResultDO add(UserLoginDO domain) {

        ResultDO result = isUserExist(domain.getUsername());

        if(!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        UserLoginEntity entity = new UserLoginEntity();
        result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        entity.setCreateDate(Calendar.getInstance().getTime());
        entity.setModifiDate(entity.getCreateDate());
        entity.setModifier(entity.getCreator());
        String salt = ByteSource.Util.bytes(domain.getUsername()).toHex();
        String password = PasswordUtil.getPassword(domain.getPassword(),salt);
        entity.setPassword(password);
        entity.setSalt(salt);

        int res = -1;
        try {
            res = userLoginMapper.insert(entity);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_ADD_ERROR);
            logger.debug("error code：" + ErrorCode.USER_ADD_ERROR.getCode() + " msg" + ErrorCode.USER_ADD_ERROR.getMsg());
            return result;
        }

        result = roleService.bindRole(entity.getId(), domain.getRoleId());

        if(!result.isSuccess()) {
            try {
                throw new Exception(result.getErrorCode().getMsg());
            } catch (Exception e) {
                logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return result;
            }

        }
        domain.getUserDetailDO().setId(entity.getId());
        result = addDetail(domain.getUserDetailDO());

        if(!result.isSuccess()) {
            try {
                throw new Exception(result.getErrorCode().getMsg());
            } catch (Exception e) {
                logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return result;
            }

        }
        return result;
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    private ResultDO addDetail(UserDetailDO domain) {

        UserDetailEntity entity = new UserDetailEntity();
        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        entity.setCreateDate(Calendar.getInstance().getTime());
        entity.setModifiDate(entity.getCreateDate());
        entity.setModifier(entity.getCreator());

        int res = -1;
        try {
            res = userDetailMapper.insert(entity);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_ADD_ERROR);
            logger.debug("error code：" + ErrorCode.USER_ADD_ERROR.getCode() + " msg" + ErrorCode.USER_ADD_ERROR.getMsg());
            return result;
        }
        return result;
    }

    public ResultDO isUserExist(String username) {

        ResultDO result = new ResultSupport();

        QueryWrapper<UserLoginEntity> queryWrapper = new QueryWrapper<UserLoginEntity>();
        //修改查询用户是否存在为等于查询
        queryWrapper.lambda().eq(UserLoginEntity::getUsername, username).eq(UserLoginEntity::getIsDelete, Constant.IS_DELETE_FALSE);
//        queryWrapper.like("username", username);

        int count = 0;
        try {
            count = userLoginMapper.selectCount(queryWrapper);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        if(count == 1) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_NAME_IS_EXIST);
        }

        return result;
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    public ResultDO editPassword(UserLoginDO domain) {

        ResultDO result = new ResultSupport();

        UserLoginEntity entity = null;
        try {
            entity = userLoginMapper.selectOne(Wrappers.<UserLoginEntity>lambdaQuery().eq(UserLoginEntity::getUsername, domain.getUsername()));
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        if(entity == null){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_LOGIN_IS_NO_EXIST);
            logger.debug("error code：" + ErrorCode.USER_LOGIN_IS_NO_EXIST.getCode() + " msg" + ErrorCode.USER_LOGIN_IS_NO_EXIST.getMsg());
            return result;
        }

        String salt = ByteSource.Util.bytes(domain.getUsername()).toHex();

        String oldPassword = PasswordUtil.getPassword(domain.getOldPassword(),salt);

        if(!entity.getPassword().equals(oldPassword)){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_ACCOUNT_PASSWORD_ERROR);
            logger.debug("error code：" + ErrorCode.USER_ACCOUNT_PASSWORD_ERROR.getCode() + " msg" + ErrorCode.USER_ACCOUNT_PASSWORD_ERROR.getMsg());
            return result;
        }

        String userId = entity.getId();
        entity = new UserLoginEntity();
        entity.setModifiDate(Calendar.getInstance().getTime());
        entity.setModifier(domain.getModifier());
        String password = PasswordUtil.getPassword(domain.getPassword(),salt);
        entity.setPassword(password);
        entity.setSalt(salt);
        entity.setId(userId);

        int res = -1;
        try {
            res = userLoginMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_EDIT_PASSWORD_ERROR);
            logger.debug("error code：" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getCode() + " msg" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getMsg());
            return result;
        }

        //强制剔除登陆用户(清除缓存和Session)
        ShiroUtils.deleteCache(domain.getUsername(),true);

        return result;
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    public ResultDO edit(UserLoginDO domain) {

        UserDetailEntity entity = new UserDetailEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain.getUserDetailDO());
        if (!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        entity.setModifiDate(Calendar.getInstance().getTime());
        //修改用户角色
        if(domain.getRoleId() != null && domain.getRoleId().length > 0){
            try {
                userRoleMapper.delete(Wrappers.<UserRoleEntity>lambdaQuery().eq(UserRoleEntity::getUserId, domain.getId()));
            } catch (Exception e) {
                logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return result;
            }
            //绑定之前删除该用户所有的角色
            result = roleService.bindRole(entity.getId(), domain.getRoleId());
            if(!result.isSuccess()) {
                try {
                    throw new Exception(result.getErrorCode().getMsg());
                } catch (Exception e) {
                    logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return result;
                }
            }
        }

        int res = -1;
        try {
            res = userDetailMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_EDIT_ERROR);
            logger.debug("error code：" + ErrorCode.USER_EDIT_ERROR.getCode() + " msg" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getMsg());
            return result;
        }

        return result;
    }


    public ResultDO getUserByName(String username) {

        ResultDO result = new ResultSupport();

        UserLoginEntity entity = null;

        QueryWrapper<UserLoginEntity> queryWrapper = new QueryWrapper<UserLoginEntity>();
        queryWrapper.lambda().eq(UserLoginEntity::getUsername, username).eq(UserLoginEntity::getIsDelete, Constant.IS_DELETE_FALSE);
        try {
            entity = userLoginMapper.selectOne(queryWrapper);
        } catch(Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        if(entity == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_DOES_NOT_EXIST);
            logger.debug("error code：" + ErrorCode.USER_DOES_NOT_EXIST.getCode() + " msg" + ErrorCode.USER_DOES_NOT_EXIST.getMsg());
            return result;
        }

        UserLoginDO domain = getDomain(entity);

        if(domain == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_COPY_OBJECT_ERROR);
            logger.debug("error code：" + ErrorCode.SYSTEM_COPY_OBJECT_ERROR.getCode() + " msg" + ErrorCode.SYSTEM_COPY_OBJECT_ERROR.getMsg());
            return result;
        }

        ResultDO detail = getDetail(entity.getId());
        if (!detail.isSuccess()){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_DOES_NOT_EXIST);
            logger.debug("error code：" + ErrorCode.USER_DOES_NOT_EXIST.getCode() + " msg" + ErrorCode.USER_DOES_NOT_EXIST.getMsg());
            return result;
        }
        try {
            UserDetailDO detailModel = (UserDetailDO)detail.getModel(ResultDO.FIRST_MODEL_KEY);
            domain.setUserDetailDO(detailModel);
        }catch (Exception e){
            logger.debug(e.getMessage());
        }

        result = roleService.getRoleByUserId(domain.getId());

        if(!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        List<PermissionDO> permissionList = (List<PermissionDO>) result.getModel(ResultDO.SECOND_MODEL_KEY);

        domain.setRoles((List<RoleDO>) result.getModel(ResultDO.FIRST_MODEL_KEY));
        domain.setPermissiones(permissionList);
        domain.setMenuTree((List<MenuTreeDO>) result.getModel(ResultDO.THIRD_MODEL_KEY));

        String[] permissionArray = null;

        if(permissionList == null){
            permissionArray = null;
        } else {
            permissionArray = permissionList.stream().filter(Objects::nonNull).filter( item -> {
                return item.getType() == Integer.parseInt(Constant.BUTT);
            }).map(PermissionDO::getCode).toArray(String[]::new);
        }
        domain.setPermissionCode(permissionArray);

        result = userLoginLogService.getLoginFailureCount(entity.getId());

        if(!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }
        Integer loginFailurCount = (Integer) result.getModel(ResultDO.FIRST_MODEL_KEY);
        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);
        result.setModel(ResultDO.SECOND_MODEL_KEY, loginFailurCount);
        return result;
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    public ResultDO editStatus(UserLoginDO domain) {
        ResultDO result = new ResultSupport();

        UserLoginEntity entity = new UserLoginEntity();
        entity.setId(domain.getId());
        entity.setStatus(domain.getStatus());
        entity.setModifier(domain.getUsername());
        entity.setModifiDate(Calendar.getInstance().getTime());

        int res = -1;
        try {
            res = userLoginMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_EDIT_ERROR);
            logger.debug("error code：" + ErrorCode.USER_EDIT_ERROR.getCode() + " msg" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getMsg());
            return result;
        }

        return result;
    }


    public ResultDO get(String id) {
        ResultDO result = new ResultSupport();
        UserLoginEntity entity = null;
        try {
            entity = userLoginMapper.selectById(id);
        } catch(Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        UserLoginDO domain = getDomain(entity);
        if(StringUtils.isNotEmpty(domain.getMerchantId())){
            result = merchantService.get(domain.getMerchantId());
            if(result.isSuccess()){
                MerchantDO merchant = (MerchantDO) result.getModel(ResultDO.FIRST_MODEL_KEY);
                domain.setMerchantName(merchant.getMerchantName());
            }
        }
        result = getDetail(id);
        if(!result.isSuccess()) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_GET_ERROR);
            logger.debug("error code：" + ErrorCode.USER_GET_ERROR.getCode() + " msg" + ErrorCode.USER_GET_ERROR.getMsg());
            return result;
        }
        domain.setUserDetailDO((UserDetailDO) result.getModel(ResultDO.FIRST_MODEL_KEY));
        result = roleService.getRoleByUserId(domain.getId());;
        if(!result.isSuccess()) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_GET_ERROR);
            logger.debug("error code：" + ErrorCode.USER_GET_ERROR.getCode() + " msg" + ErrorCode.USER_GET_ERROR.getMsg());
            return result;
        }
        List<RoleDO> roleList = (List<RoleDO>) result.getModel(ResultDO.FIRST_MODEL_KEY);
        if(roleList != null && roleList.size() >0){
            domain.setRoleId(roleList.stream().map( item -> item.getId()).toArray(String[]::new));
        }
        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);
        return result;
    }

    @Override
    public ResultDO getByMerchantId(String merchantId) {
        ResultDO result = new ResultSupport();
        UserLoginEntity entity = null;
        try {
            entity = userLoginMapper.selectOne(Wrappers.<UserLoginEntity>lambdaQuery().eq(UserLoginEntity::getMerchantId, merchantId));
        } catch(Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        UserLoginDO domain = getDomain(entity);
        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);
        return result;
    }

    private ResultDO getDetail(String id) {

        ResultDO result = new ResultSupport();

        UserDetailEntity entity = null;

        try {
            entity = userDetailMapper.selectById(id);
        } catch(Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        UserDetailDO domain = getDomain(entity);

        if(domain == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_COPY_OBJECT_ERROR);
            logger.debug("error code：" + ErrorCode.SYSTEM_COPY_OBJECT_ERROR.getCode() + " msg" + ErrorCode.SYSTEM_COPY_OBJECT_ERROR.getMsg());
            return result;
        }

        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

        return result;
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    public ResultDO remove(String id, String modifier) {

        ResultDO result = null;

        result = roleService.unbindRoleAll(id);

        if(!result.isSuccess()) {
            logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        UserLoginEntity entity = new UserLoginEntity();

        entity.setModifiDate(Calendar.getInstance().getTime());
        entity.setModifier(modifier);
        entity.setId(id);
        entity.setIsDelete(Constant.IS_DELETE);

        int res = -1;
        try {
            res = userLoginMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_DELETE_ERROR);
            logger.debug("error code：" + ErrorCode.USER_DELETE_ERROR.getCode() + " msg" + ErrorCode.USER_DELETE_ERROR.getMsg());
            return result;
        }

        result = removeDetail(id, modifier);
        if(!result.isSuccess()) {
            try {
                throw new Exception(result.getErrorCode().getMsg());
            } catch (Exception e) {
                logger.debug("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return result;
            }

        }

        try {
            entity = userLoginMapper.selectById(id);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        // 验证成功开始踢人(清除缓存和Session)
        ShiroUtils.deleteCache(entity.getUsername(),true);

        return result;
    }

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
    private ResultDO removeDetail(String id, String modifier) {

        ResultDO result = new ResultSupport();

        UserDetailEntity entity = new UserDetailEntity();

        entity.setModifiDate(Calendar.getInstance().getTime());
        entity.setModifier(modifier);
        entity.setIsDelete(Constant.IS_DELETE);
        entity.setId(id);

        int res = -1;
        try {
            res = userDetailMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_DELETE_ERROR);
            logger.debug("error code：" + ErrorCode.USER_DELETE_ERROR.getCode() + " msg" + ErrorCode.USER_DELETE_ERROR.getMsg());
            return result;
        }

        return result;
    }


    public ResultDO find(UserQueryDO query) {

        ResultDO result = new ResultSupport();

        Page<Map<String, String>> page = new Page<>(query.getCurrentPage(),query.getPageSize());

        IPage<Map<String, Object>> iPage = null;

        Map<String, Object> param = new HashMap<>();
        if(StringUtils.isNotEmpty(query.getMerchantId())) {
            param.put("merchantId", query.getMerchantId());
        }
        if(StringUtils.isNotEmpty(query.getUsername())) {
            param.put("username", query.getUsername());
        }
        if(StringUtils.isNotEmpty(query.getRealName())) {
            param.put("realName", query.getRealName());
        }
        if(query.getType() != null && query.getType() != 0) {
            param.put("type", query.getType());
        }
        if(StringUtils.isNotEmpty(query.getTelephone())){
            param.put("telephone",query.getTelephone());
        }

        try {
            iPage = userLoginMapper.selectUserPages(page, param);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        List<UserDO> doList = iPage.getRecords().stream().map(m->{
            UserDO userDO = MapTool.map2Bean(m, UserDO.class,true);
            return userDO;
        }).collect(Collectors.toList());


        PageDO<UserDO> pageDO = new PageDO<>();

        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(doList);


        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);

        return result;
    }

    @Override
    public ResultDO selectUserByRoleId(Integer roleId) {

        ResultDO result = new ResultSupport();
        List<UserRoleEntity> userRoleList = null;
        try {
            userRoleList = userRoleMapper.selectList(Wrappers.<UserRoleEntity>lambdaQuery().eq(UserRoleEntity::getRoleId, roleId));
        } catch(Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        List<UserLoginEntity> userList = null;
        if(userRoleList != null){
            try {
                userList = userLoginMapper.selectBatchIds(userRoleList.stream().map( item -> item.getUserId()).collect(Collectors.toList()));
            } catch(Exception e) {
                e.printStackTrace();
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
                logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
                return result;
            }
        }
        List<UserLoginDO> domainList = getDomainList(userList);
        result.setModel(ResultDO.FIRST_MODEL_KEY, domainList);

        return result;
    }

    @Override
    public ResultDO resetPassword(UserLoginDO domain) {
        ResultDO result = new ResultSupport();
        UserLoginEntity entity = new UserLoginEntity();

        entity.setModifiDate(Calendar.getInstance().getTime());
        entity.setModifier(domain.getModifier());

        String salt = ByteSource.Util.bytes(domain.getUsername()).toHex();
        String password = PasswordUtil.getPassword(domain.getPassword(),salt);
        entity.setPassword(password);
        entity.setSalt(salt);
        entity.setId(domain.getId());

        int res = -1;
        try {
            res = userLoginMapper.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if(res < 0) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.USER_EDIT_PASSWORD_ERROR);
            logger.debug("error code：" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getCode() + " msg" + ErrorCode.USER_EDIT_PASSWORD_ERROR.getMsg());
            return result;
        }
        try {
            //强制剔除登陆用户(清除缓存和Session)
            ShiroUtils.deleteCache(domain.getUsername(),true);
        } catch (Exception e) {
            logger.debug("没有找到登陆的用户缓存");
        }

        return result;
    }

    private UserLoginDO getDomain(UserLoginEntity entity) {
        ResultDO result = new ResultSupport();
        //判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if(entity == null) return null;
        UserLoginDO domain = new UserLoginDO();

        if(!result.isSuccess()) {
            return null;
        }
        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }

    private UserDetailDO getDomain(UserDetailEntity entity) {

        //判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if(entity == null) return null;
        UserDetailDO domain = new UserDetailDO();

        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }

    private  List<UserLoginDO> getDomainList(List<UserLoginEntity> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<UserLoginDO> doList = new ArrayList<UserLoginDO>();

        //判断传入的list的集合的size是否大于0
        if(list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for(UserLoginEntity entity : list) {

                UserLoginDO domain = this.getDomain(entity);

                //判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
                if(domain == null) {
                    return null;
                }
                doList.add(domain);
            }
        } else {
            return null;
        }
        return doList;
    }
}
